package cn.sunshine.ymcc.mq.listener;


import cn.sunshine.ymcc.domain.PayOrder;
import cn.sunshine.ymcc.dto.PayAliNotifyDto;
import cn.sunshine.ymcc.service.IPayNotifyService;
import cn.sunshine.ymcc.service.IPayOrderService;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;

import java.nio.charset.StandardCharsets;
import java.util.Map;

//@Component  下面的注解是组合注解，可以不加
@RocketMQTransactionListener(txProducerGroup="TxPayAliNotifyGroup") // 事务监听器组名和生产者那边要一致
@Slf4j
public class AliPayTransMsgListener implements RocketMQLocalTransactionListener {
    @Autowired
    private IPayNotifyService payNotifyService;

    @Autowired
    private IPayOrderService payOrderService;
    //执行本地事务

    /**
     * 保存订单
     * 保存子订单
     *
     * @param message 消息体（保存支付单的内容）
     * @param arg 订单和子订单参数
     * @return
     */
    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message message, Object arg) {
        log.info("开始执行本地事务");
        if(arg == null){  //参数为空不能执行本地事务，直接回滚
            return RocketMQLocalTransactionState.ROLLBACK; // 回滚
        }
        Map<String,Object> map = (Map<String,Object>) arg;
        try {
            //执行本地事务（也就是保存支付单和支付流水）
            payNotifyService.updatePayOrderAndInsertFlow(map);
            return RocketMQLocalTransactionState.COMMIT;
        } catch (Exception e) {
            e.printStackTrace();
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    //检查本地事务
    /*
    * @Title: checkLocalTransaction
    * @Description: 根据订单号检查本地订单是否已经保存成功
    * @Author: Mr.Jiang
    * @Version: 1.0
    * @Date:  2022/8/22 17:21
    * @Parameters: [message]
    * @Return org.apache.rocketmq.spring.core.RocketMQLocalTransactionState
    */
    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message message) {
        try {
            byte[] body = (byte[]) message.getPayload();
            String jsonStr = new String(body, StandardCharsets.UTF_8);
            PayAliNotifyDto payAliNotifyDto = JSONObject.parseObject(jsonStr, PayAliNotifyDto.class);
            PayOrder payOrder = payOrderService.checkPayOrder(payAliNotifyDto.getOrderNo());
            if(payOrder != null && payOrder.getPayStatus() == PayOrder.STATE_SUCCESS){
                return RocketMQLocalTransactionState.COMMIT;
            }
            return RocketMQLocalTransactionState.ROLLBACK;
        } catch (Exception e) {
            e.printStackTrace();
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }
}
